home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / JIIM.C < prev    next >
C/C++ Source or Header  |  1995-02-19  |  33KB  |  1,423 lines

  1. /*
  2.  * JIIM.C
  3.  *
  4.  * Generates Inverse Julia in real time, lets move a cursor which determines
  5.  * the J-set.
  6.  *
  7.  *  The J-set is generated in a fixed-size window, a third of the screen.
  8.  *
  9.  * The routines used to set/move the cursor and to save/restore the
  10.  * window were "borrowed" from editpal.c (TW - now we *use* the editpal code)
  11.  *     (if you don't know how to write good code, look for someone who does)
  12.  *
  13.  *    JJB  [jbuhler@gidef.edu.ar]
  14.  *    TIW  Tim Wegner
  15.  *    MS   Michael Snyder
  16.  *    KS   Ken Shirriff
  17.  * Revision History:
  18.  *
  19.  *        7-28-92       JJB  Initial release out of editpal.c
  20.  *        7-29-92       JJB  Added SaveRect() & RestoreRect() - now the
  21.  *                           screen is restored after leaving.
  22.  *        7-30-92       JJB  Now, if the cursor goes into the window, the
  23.  *                           window is moved to the other side of the screen.
  24.  *                           Worked from the first time!
  25.  *        10-09-92      TIW  A major rewrite that merged cut routines duplicated
  26.  *                           in EDITPAL.C and added orbits feature.
  27.  *        11-02-92      KS   Made cursor blink
  28.  *        11-18-92      MS   Altered Inverse Julia to use MIIM method.
  29.  *      11-25-92    MS   Modified MIIM support routines to better be
  30.  *                 shared with stand-alone inverse julia in
  31.  *                 LORENZ.C, and to use DISKVID for swap space.
  32.  *        05-05-93      TIW  Boy this change file really got out of date.
  33.  *                 Added orbits capability, various commands, some 
  34.  *                  of Dan Farmer's ideas like circles and lines 
  35.  *                 connecting orbits points.
  36.  *        12-18-93      TIW  Removed use of float only for orbits, fixed a
  37.  *                 helpmode bug.
  38.  *    
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44.  
  45. #ifndef XFRACT
  46. #include <stdarg.h>
  47. #include <dos.h>     /* for FP_SEG & FP_OFF */
  48. #else
  49. #include <varargs.h>
  50. #endif
  51.  
  52. #include <math.h>
  53.  
  54. #ifdef __TURBOC__
  55. #   include <mem.h>   /* to get mem...() declarations */
  56. #endif
  57.  
  58. #include "helpdefs.h"
  59. #include "fractint.h" /* for overlay stuff */
  60. #include "fractype.h"
  61. #include "prototyp.h"
  62.  
  63. #define FAR_RESERVE     8192L     /* amount of far mem we will leave avail. */
  64. #define MAXRECT         1024      /* largest width of SaveRect/RestoreRect */
  65.  
  66. #define newx(size)     mem_alloc(size)
  67. #define delete(block)
  68.  
  69. enum stored_at_values
  70.    {
  71.    NOWHERE,
  72.    DISK,
  73.    MEMORY
  74.    } ;
  75.  
  76. int show_numbers =0;              /* toggle for display of coords */
  77. int stored_at;
  78. char far *memory = NULL;            /* pointer to saved rectangle */
  79. FILE *file;
  80. int windows = 0;               /* windows management system */
  81.  
  82. static int xc, yc;                       /* corners of the window */
  83. static int xd, yd;                       /* dots in the window    */
  84. double xcjul = BIG;
  85. double ycjul = BIG;
  86.  
  87. void displays(int x, int y, int fg, int bg, char *str, int len)
  88. {
  89.    int i;
  90.    for(i=0;i<len; i++)
  91.       displayc(x+i*8, y, fg, bg, str[i]);
  92. }
  93.  
  94. /* circle routines from Dr. Dobbs June 1990 */
  95. int xbase, ybase;
  96. unsigned int xAspect, yAspect;
  97.  
  98. void SetAspect(double aspect)
  99. {
  100.    xAspect = 0;
  101.    yAspect = 0;
  102.    aspect = fabs(aspect);
  103.    if (aspect != 1.0)
  104.       if (aspect > 1.0)
  105.      yAspect = (unsigned int)(65536.0 / aspect);
  106.       else
  107.      xAspect = (unsigned int)(65536.0 * aspect);
  108. }
  109.  
  110. void _fastcall c_putcolor(int x, int y, int color)
  111.    {
  112.    /* avoid writing outside window */
  113.    if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd )
  114.       return ;
  115.    if(y >= sydots - show_numbers) /* avoid overwriting coords */
  116.       return;
  117.    if(windows == 2) /* avoid overwriting fractal */
  118.       if (0 <= x && x < xdots && 0 <= y && y < ydots)
  119.      return;
  120.    putcolor(x, y, color);
  121.    }
  122.  
  123.  
  124. int  c_getcolor(int x, int y)
  125.    {
  126.    /* avoid reading outside window */
  127.    if ( x < xc || y < yc || x >= xc + xd || y >= yc + yd )
  128.       return 1000;
  129.    if(y >= sydots - show_numbers) /* avoid overreading coords */
  130.       return 1000;
  131.    if(windows == 2) /* avoid overreading fractal */
  132.       if (0 <= x && x < xdots && 0 <= y && y < ydots)
  133.      return 1000;
  134.    return getcolor(x, y);
  135.    }
  136.  
  137. void circleplot(int x, int y, int color)
  138. {
  139.    if (xAspect == 0)
  140.       if (yAspect == 0)
  141.      c_putcolor(x+xbase, y+ybase,color);
  142.       else
  143.      c_putcolor(x+xbase, (short)(ybase + (((long) y * (long) yAspect) >> 16)),color);
  144.    else
  145.       c_putcolor((int)(xbase + (((long) x * (long) xAspect) >> 16)), y+ybase, color);
  146. }
  147.  
  148. void plot8(int x, int y, int color)
  149. {
  150.    circleplot(x,y,color);
  151.    circleplot(-x,y,color);
  152.    circleplot(x,-y,color);
  153.    circleplot(-x,-y,color);
  154.    circleplot(y,x,color);
  155.    circleplot(-y,x,color);
  156.    circleplot(y,-x,color);
  157.    circleplot(-y,-x,color);
  158. }
  159.  
  160. void circle(int radius, int color)
  161. {
  162.    int x,y,sum;
  163.  
  164.    x = 0;
  165.    y = radius << 1;
  166.    sum = 0;
  167.  
  168.    while (x <= y)
  169.    {
  170.       if ( !(x & 1) )   /* plot if x is even */
  171.      plot8( x >> 1, (y+1) >> 1, color);
  172.       sum += (x << 1) + 1;
  173.       x++;
  174.       if (sum > 0)
  175.       {
  176.      sum -= (y << 1) - 1;
  177.      y--;
  178.       }
  179.    }
  180. }
  181.  
  182.  
  183. /*
  184.  * MIIM section:
  185.  *
  186.  * Global variables and service functions used for computing
  187.  * MIIM Julias will be grouped here (and shared by code in LORENZ.C)
  188.  *
  189.  */
  190.  
  191.  
  192.  long   ListFront, ListBack, ListSize;  /* head, tail, size of MIIM Queue */
  193.  long   lsize, lmax;            /* how many in queue (now, ever) */
  194.  int    maxhits = 1;
  195.  int    OKtoMIIM;
  196.  int    SecretExperimentalMode;
  197.  float  luckyx = 0, luckyy = 0;
  198.  
  199. static void fillrect(int x, int y, int width, int depth, int color)
  200. {
  201.    /* fast version of fillrect */
  202.    if(hasinverse == 0)
  203.       return;
  204.    memset(dstack, color % colors, width);
  205.    while (depth-- > 0)
  206.    {
  207.       if(keypressed()) /* we could do this less often when in fast modes */
  208.          return;
  209.       putrow(x, y++, width, (char *)dstack);
  210.    }
  211. }
  212.  
  213. /*
  214.  * Queue/Stack Section:
  215.  *
  216.  * Defines a buffer that can be used as a FIFO queue or LIFO stack.
  217.  */
  218.  
  219. int
  220. QueueEmpty()        /* True if NO points remain in queue */
  221. {
  222.    return (ListFront == ListBack);
  223. }
  224.  
  225. #if 0 /* not used */
  226. int
  227. QueueFull()        /* True if room for NO more points in queue */
  228. {
  229.    return (((ListFront + 1) % ListSize) == ListBack);
  230. }
  231. #endif
  232.  
  233. int
  234. QueueFullAlmost()    /* True if room for ONE more point in queue */
  235. {
  236.    return (((ListFront + 2) % ListSize) == ListBack);
  237. }
  238.  
  239. void
  240. ClearQueue()
  241. {
  242.    ListFront = ListBack = lsize = lmax = 0;
  243. }
  244.  
  245.  
  246. /*
  247.  * Queue functions for MIIM julia:
  248.  * move to JIIM.C when done
  249.  */
  250.  
  251. int Init_Queue(unsigned long request)
  252. {
  253.    if (dotmode == 11)
  254.    {
  255.       static FCODE nono[] = "Don't try this in disk video mode, kids...\n";
  256.       stopmsg(0, nono);
  257.       ListSize = 0;
  258.       return 0;
  259.    }
  260.  
  261. #if 0
  262.    if (xmmquery() && debugflag != 420)    /* use LARGEST extended mem */
  263.       if ((largest = xmmlongest()) > request / 128)
  264.      request   = (unsigned long) largest * 128L;
  265. #endif
  266.  
  267.    for (ListSize = request; ListSize > 1024; ListSize -= 512)
  268.       switch (common_startdisk(ListSize * 8, 1, 256))
  269.       {
  270.      case 0:                        /* success */
  271.         ListFront = ListBack = 0;
  272.         lsize = lmax = 0;
  273.         return 1;
  274.      case -1:
  275.         continue;            /* try smaller queue size */
  276.      case -2:
  277.         ListSize = 0;               /* cancelled by user      */
  278.         return 0;
  279.       }
  280.  
  281.    /* failed to get memory for MIIM Queue */
  282.    ListSize = 0;
  283.    return 0;
  284. }
  285.  
  286. void
  287. Free_Queue()
  288. {
  289.    enddisk();
  290.    ListFront = ListBack = ListSize = lsize = lmax = 0;
  291. }
  292.  
  293. int
  294. PushLong(long x, long y)
  295. {
  296.    if (((ListFront + 1) % ListSize) != ListBack)
  297.    {
  298.       if (ToMemDisk(8*ListFront, sizeof(x), &x) &&
  299.       ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y))
  300.       {
  301.      ListFront = (ListFront + 1) % ListSize;
  302.      if (++lsize > lmax)
  303.      {
  304.         lmax   = lsize;
  305.         luckyx = (float)x;
  306.         luckyy = (float)y;
  307.      }
  308.      return 1;
  309.       }
  310.    }
  311.    return 0;            /* fail */
  312. }
  313.  
  314. int
  315. PushFloat(float x, float y)
  316. {
  317.    if (((ListFront + 1) % ListSize) != ListBack)
  318.    {
  319.       if (ToMemDisk(8*ListFront, sizeof(x), &x) &&
  320.       ToMemDisk(8*ListFront +sizeof(x), sizeof(y), &y))
  321.       {
  322.      ListFront = (ListFront + 1) % ListSize;
  323.      if (++lsize > lmax)
  324.      {
  325.         lmax   = lsize;
  326.         luckyx = x;
  327.         luckyy = y;
  328.      }
  329.      return 1;
  330.       }
  331.    }
  332.    return 0;            /* fail */
  333. }
  334.  
  335. _CMPLX
  336. PopFloat()
  337. {
  338.    _CMPLX pop;
  339.    float  popx, popy;
  340.  
  341.    if (!QueueEmpty())
  342.    {
  343.       ListFront--;
  344.       if (ListFront < 0)
  345.       ListFront = ListSize - 1;
  346.       if (FromMemDisk(8*ListFront, sizeof(popx), &popx) &&
  347.       FromMemDisk(8*ListFront +sizeof(popx), sizeof(popy), &popy))
  348.       {
  349.      pop.x = popx;
  350.      pop.y = popy;
  351.      --lsize;
  352.       }
  353.       return pop;
  354.    }
  355.    pop.x = 0;
  356.    pop.y = 0;
  357.    return pop;
  358. }
  359.  
  360. LCMPLX
  361. PopLong()
  362. {
  363.    LCMPLX pop;
  364.  
  365.    if (!QueueEmpty())
  366.    {
  367.       ListFront--;
  368.       if (ListFront < 0)
  369.       ListFront = ListSize - 1;
  370.       if (FromMemDisk(8*ListFront, sizeof(pop.x), &pop.x) &&
  371.       FromMemDisk(8*ListFront +sizeof(pop.x), sizeof(pop.y), &pop.y))
  372.      --lsize;
  373.       return pop;
  374.    }
  375.    pop.x = 0;
  376.    pop.y = 0;
  377.    return pop;
  378. }
  379.  
  380. int
  381. EnQueueFloat(float x, float y)
  382. {
  383.    return PushFloat(x, y);
  384. }
  385.  
  386. int
  387. EnQueueLong(long x, long y)
  388. {
  389.    return PushLong(x, y);
  390. }
  391.  
  392. _CMPLX
  393. DeQueueFloat()
  394. {
  395.    _CMPLX out;
  396.    float outx, outy;
  397.  
  398.    if (ListBack != ListFront)
  399.    {
  400.       if (FromMemDisk(8*ListBack, sizeof(outx), &outx) &&
  401.       FromMemDisk(8*ListBack +sizeof(outx), sizeof(outy), &outy))
  402.       {
  403.      ListBack = (ListBack + 1) % ListSize;
  404.      out.x = outx;
  405.      out.y = outy;
  406.      lsize--;
  407.       }
  408.       return out;
  409.    }
  410.    out.x = 0;
  411.    out.y = 0;
  412.    return out;
  413. }
  414.  
  415. LCMPLX
  416. DeQueueLong()
  417. {
  418.    LCMPLX out;
  419.    out.x = 0;
  420.    out.y = 0;
  421.  
  422.    if (ListBack != ListFront)
  423.    {
  424.       if (FromMemDisk(8*ListBack, sizeof(out.x), &out.x) &&
  425.       FromMemDisk(8*ListBack +sizeof(out.x), sizeof(out.y), &out.y))
  426.       {
  427.      ListBack = (ListBack + 1) % ListSize;
  428.      lsize--;
  429.       }
  430.       return out;
  431.    }
  432.    out.x = 0;
  433.    out.y = 0;
  434.    return out;
  435. }
  436.  
  437.  
  438.  
  439. /*
  440.  * End MIIM section;
  441.  */
  442.  
  443.  
  444.  
  445. static BOOLEAN MemoryAlloc(long size)
  446. {
  447.    char far *temp;
  448.    
  449.    if (debugflag == 420)
  450.       return(FALSE);
  451.    temp = (char far *)farmemalloc(FAR_RESERVE);   /* minimum free space */
  452.  
  453.    if (temp == NULL)
  454.    {
  455.       stored_at = NOWHERE;
  456.       return (FALSE);   /* can't do it */
  457.    }
  458.  
  459.    memory = (char far *)farmemalloc( size );
  460.    farmemfree(temp);
  461.  
  462.    if ( memory == NULL )
  463.    {
  464.       stored_at = NOWHERE;
  465.       return (FALSE);
  466.    }
  467.    else
  468.    {
  469.       stored_at = MEMORY;
  470.       return (TRUE);
  471.    }
  472. }
  473.  
  474.  
  475. static void SaveRect(int x, int y, int width, int depth)
  476. {
  477.    char buff[MAXRECT];
  478.    int  yoff;
  479.    if(hasinverse == 0)
  480.       return;
  481.    /* first, do any de-allocationg */
  482.  
  483.    switch( stored_at )
  484.    {
  485.    case NOWHERE:
  486.       break;
  487.  
  488.    case DISK:
  489.       break;
  490.  
  491.    case MEMORY:
  492.       if (memory != NULL)
  493.       {
  494.      farmemfree(memory);
  495.       }
  496.       memory = NULL;
  497.       break;
  498.    }
  499.  
  500.    /* allocate space and store the rect */
  501.  
  502.    memset(dstack, color_dark, width);
  503.    if ( MemoryAlloc( (long)width*(long)depth) )
  504.    {
  505.       char far  *ptr = memory;
  506.       char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  507.  
  508.       Cursor_Hide();
  509.       for (yoff=0; yoff<depth; yoff++)
  510.       {
  511.      getrow(x, y+yoff, width, buff);
  512.      putrow(x, y+yoff, width, (char *)dstack);
  513.      movedata(FP_SEG(bufptr), FP_OFF(bufptr), FP_SEG(ptr), FP_OFF(ptr), width);
  514.      ptr = (char far *)normalize(ptr+width);
  515.       }
  516.       Cursor_Show();
  517.    }
  518.  
  519.    else /* to disk */
  520.    {
  521.       stored_at = DISK;
  522.  
  523.       if ( file == NULL )
  524.       {
  525.      file = dir_fopen(tempdir,scrnfile, "w+b");
  526.      if (file == NULL)
  527.      {
  528.         stored_at = NOWHERE;
  529.         buzzer(3);
  530.         return ;
  531.      }
  532.       }
  533.  
  534.       rewind(file);
  535.       Cursor_Hide();
  536.       for (yoff=0; yoff<depth; yoff++)
  537.       {
  538.      getrow(x, y+yoff, width, buff);
  539.      putrow(x, y+yoff, width, (char *)dstack);
  540.      if ( fwrite(buff, width, 1, file) != 1 )
  541.      {
  542.         buzzer(3);
  543.         break;
  544.      }
  545.       }
  546.       Cursor_Show();
  547.    }
  548. }
  549.  
  550.  
  551. static void RestoreRect(int x, int y, int width, int depth)
  552. {
  553.    char buff[MAXRECT];
  554.    int  yoff;
  555.    if(hasinverse == 0)
  556.       return;
  557.  
  558.    switch ( stored_at )
  559.    {
  560.    case DISK:
  561.       rewind(file);
  562.       Cursor_Hide();
  563.       for (yoff=0; yoff<depth; yoff++)
  564.       {
  565.      if ( fread(buff, width, 1, file) != 1 )
  566.      {
  567.         buzzer(3);
  568.         break;
  569.      }
  570.      putrow(x, y+yoff, width, buff);
  571.       }
  572.       Cursor_Show();
  573.       break;
  574.  
  575.    case MEMORY:
  576.       {
  577.      char far  *ptr = memory;
  578.      char far  *bufptr = buff; /* MSC needs this indirection to get it right */
  579.  
  580.      Cursor_Hide();
  581.      for (yoff=0; yoff<depth; yoff++)
  582.      {
  583.         movedata(FP_SEG(ptr), FP_OFF(ptr), FP_SEG(bufptr), FP_OFF(bufptr), width);
  584.         putrow(x, y+yoff, width, buff);
  585.         ptr = (char far *)normalize(ptr+width);
  586.      }
  587.      Cursor_Show();
  588.      break;
  589.       }
  590.  
  591.    case NOWHERE:
  592.       break;
  593.    } /* switch */
  594. }
  595.  
  596. /*
  597.  * interface to FRACTINT
  598.  */
  599.  
  600. /* the following macros and function call the setup, per_pixel, and orbit
  601.    routines and calculate an orbit at row 0 column 0. Have to save and 
  602.    restore the first elements of dx0 ... dy1 as well as row and col */
  603.  
  604. #define PER_IMAGE   (fractalspecific[fractype].per_image)
  605. #define PER_PIXEL   (fractalspecific[fractype].per_pixel)
  606. #define ORBITCALC   (fractalspecific[fractype].orbitcalc)
  607.  
  608. int do_fractal_routines(double cr, double ci, int (*func)(void))
  609. {
  610.    int ret;
  611.    int old_row, old_col;
  612.    old_row = row;  old_col = col;
  613.    row = col = 0;
  614.    if(integerfractal)
  615.    {
  616.       long old_lx0, old_lx1, old_ly0, old_ly1;
  617.       old_lx0 = *lx0; old_lx1 = *lx1;
  618.       old_ly0 = *ly0; old_ly1 = *ly1;
  619.       *lx0 = (long)(cr*fudge); *ly0 = (long)(ci*fudge); *lx1 = *ly1 = 0L;
  620.       ret = func();
  621.       *lx0 = old_lx0; *lx1 = old_lx1;
  622.       *ly0 = old_ly0; *ly1 = old_ly1;
  623.       old.x = lold.x; old.x /= fudge;
  624.       old.y = lold.y; old.y /= fudge;
  625.       init.x = linit.x; init.x /= fudge;
  626.       init.y = linit.y; init.y /= fudge;
  627.    }
  628.    else
  629.    {
  630.       double old_dx0, old_dx1, old_dy0, old_dy1;
  631.       old_dx0 = *dx0; old_dx1 = *dx1;
  632.       old_dy0 = *dy0; old_dy1 = *dy1;
  633.       *dx0 = cr; *dy0 = ci; *dx1 = *dy1 = 0.0;
  634.       ret = func();
  635.       *dx0 = old_dx0; *dx1 = old_dx1;
  636.       *dy0 = old_dy0; *dy1 = old_dy1;
  637.    }
  638.    row = old_row;  col = old_col;
  639.    return(ret);
  640. }
  641.  
  642.  
  643. void Jiim(int which)         /* called by fractint */
  644. {
  645.    struct affine cvt;
  646.    int exact = 0;
  647.    int oldhelpmode;
  648.    int count = 0;            /* coloring julia */
  649.    static int mode = 0;      /* point, circle, ... */
  650.    int       oldlookatmouse = lookatmouse;
  651.    double cr, ci, r;
  652.    int xfactor, yfactor;             /* aspect ratio          */
  653.  
  654.    int xoff, yoff;                   /* center of the window  */
  655.    int x, y;
  656.    int still, kbdchar= -1;
  657.    int xcrsr,ycrsr;     /* coords of the cursor / offsets to move it  */
  658.    long iter;
  659.    int color;
  660.    float zoom;
  661.    int oldsxoffs, oldsyoffs;
  662.    int savehasinverse;
  663.    int (*oldcalctype)(void);
  664.    int old_x, old_y;
  665.    double aspect;
  666.    static int randir = 0;
  667.    static int rancnt = 0;
  668.    static _CMPLX SaveC = {-3000.0, -3000.0};
  669.    int actively_computing = 1;
  670.    int first_time = 1;
  671.    int old_debugflag;
  672.    
  673.    old_debugflag = debugflag;
  674.    /* must use standard fractal or be calcfroth */
  675.    if(fractalspecific[fractype].calctype != StandardFractal
  676.        && fractalspecific[fractype].calctype != calcfroth)
  677.        return;
  678.    oldhelpmode = helpmode;
  679.    if(which == JIIM)
  680.       helpmode = HELP_JIIM;
  681.    else
  682.    {
  683.       helpmode = HELP_ORBITS;
  684.       hasinverse = 1;
  685.       /* Earth to Chuck Ebbert - remove this code when your code supports
  686.          my changes to PARSER.C */
  687.       if(fractype == FFORMULA)
  688.       {
  689.          debugflag = 90;
  690.       }
  691.    }
  692.    oldsxoffs = sxoffs;
  693.    oldsyoffs = syoffs;
  694.    oldcalctype = calctype;
  695.    show_numbers = 0;
  696.    using_jiim = 1;
  697.    mem_init(strlocn, 10*1024);
  698.    line_buff = newx(max(sxdots,sydots));
  699.    aspect = ((double)xdots*3)/((double)ydots*4);  /* assumes 4:3 */
  700.      actively_computing = 1;
  701.    SetAspect(aspect);
  702.    lookatmouse = 3;
  703.    Cursor_Construct();
  704.  
  705. /*
  706.  * MIIM code:
  707.  * Grab far memory for Queue/Stack before SaveRect gets it.
  708.  */
  709.    OKtoMIIM  = 0;
  710.    if (which == JIIM && debugflag != 300)
  711.       OKtoMIIM = Init_Queue((long)8*1024); /* Queue Set-up Successful? */
  712.  
  713.    maxhits = 1;
  714.    if (which == ORBIT)
  715.       plot = c_putcolor;             /* for line with clipping */
  716.  
  717. /*
  718.  * end MIIM code.
  719.  */
  720.  
  721.  
  722.    if(sxoffs != 0 || syoffs != 0) /* we're in view windows */
  723.    {
  724.       savehasinverse = hasinverse;
  725.       hasinverse = 1;
  726.       SaveRect(0,0,xdots,ydots);
  727.       sxoffs = 0;
  728.       syoffs = 0;
  729.       RestoreRect(0,0,xdots,ydots);
  730.       hasinverse = savehasinverse;
  731.    }
  732.  
  733.    if(which == ORBIT)
  734.       (*PER_IMAGE)();
  735.    else
  736.       color = color_bright;
  737.  
  738.    if(xdots == sxdots || ydots == sydots ||
  739.        sxdots-xdots < sxdots/3 ||
  740.        sydots-ydots < sydots/3 ||
  741.        xdots >= MAXRECT )
  742.    {
  743.       /* this mode puts orbit/julia in an overlapping window 1/3 the size of
  744.      the physical screen */
  745.       windows = 0; /* full screen or large view window */
  746.       xd = sxdots / 3;
  747.       yd = sydots / 3;
  748.       xc = xd * 2;
  749.       yc = yd * 2;
  750.       xoff = xd * 5 / 2;
  751.       yoff = yd * 5 / 2;
  752.    }
  753.    else if(xdots > sxdots/3 && ydots > sydots/3)
  754.    {
  755.       /* Julia/orbit and fractal don't overlap */
  756.       windows = 1;
  757.       xd = sxdots-xdots;
  758.       yd = sydots-ydots;
  759.       xc = xdots;
  760.       yc = ydots;
  761.       xoff = xc + xd/2;
  762.       yoff = yc + yd/2;
  763.  
  764.    }
  765.    else
  766.    {
  767.       /* Julia/orbit takes whole screen */
  768.       windows = 2;
  769.       xd = sxdots;
  770.       yd = sydots;
  771.       xc = 0;
  772.       yc = 0;
  773.       xoff = xd/2;
  774.       yoff = yd/2;
  775.    }
  776.  
  777.    xfactor = (int)(xd/5.33);
  778.    yfactor = (int)(-yd/4);
  779.  
  780.    if(windows == 0)
  781.       SaveRect(xc,yc,xd,yd);
  782.    else if(windows == 2)  /* leave the fractal */
  783.    {
  784.       fillrect(xdots, yc, xd-xdots, yd, color_dark);
  785.       fillrect(xc   , ydots, xdots, yd-ydots, color_dark);
  786.    }
  787.    else  /* blank whole window */
  788.       fillrect(xc, yc, xd, yd, color_dark);
  789.  
  790.    setup_convert_to_screen(&cvt);
  791.  
  792.    /* reuse last location if inside window */
  793.    xcrsr = (int)(cvt.a*SaveC.x + cvt.b*SaveC.y + cvt.e + .5);
  794.    ycrsr = (int)(cvt.c*SaveC.x + cvt.d*SaveC.y + cvt.f + .5);
  795.    if(xcrsr < 0 || xcrsr >= xdots ||
  796.       ycrsr < 0 || ycrsr >= ydots)
  797.    {
  798.       cr = (xxmax + xxmin) / 2.0;
  799.       ci = (yymax + yymin) / 2.0;
  800.    }
  801.    else
  802.    {
  803.       cr = SaveC.x;
  804.       ci = SaveC.y;
  805.    }
  806.  
  807.    old_x = old_y = -1;
  808.  
  809.    xcrsr = (int)(cvt.a*cr + cvt.b*ci + cvt.e + .5);
  810.    ycrsr = (int)(cvt.c*cr + cvt.d*ci + cvt.f + .5);
  811.  
  812.    Cursor_SetPos(xcrsr, ycrsr);
  813.    Cursor_Show();
  814.    color = color_bright;
  815.  
  816.    iter = 1;
  817.    still = 1;
  818.    zoom = 1;
  819.  
  820. #ifdef XFRACT
  821.    Cursor_StartMouseTracking();
  822. #endif
  823.  
  824.    while (still)
  825.    {
  826.       int dxcrsr, dycrsr;
  827.       if (actively_computing) {
  828.       Cursor_CheckBlink();
  829.       } else {
  830.       Cursor_WaitKey();
  831.       }
  832.       if(keypressed() || first_time) /* prevent burning up UNIX CPU */
  833.       {
  834.      first_time = 0;
  835.      while(keypressed())
  836.      {
  837.         Cursor_WaitKey();
  838.         kbdchar = getakey();
  839.  
  840.         dxcrsr = dycrsr = 0;
  841.         xcjul = BIG;
  842.         ycjul = BIG;
  843.         switch (kbdchar)
  844.         {
  845.             case 1143:    /* ctrl - keypad 5 */
  846.         case 1076:    /* keypad 5        */
  847.            break;     /* do nothing */
  848.         case CTL_PAGE_UP:
  849.            dxcrsr = 4;
  850.            dycrsr = -4;
  851.            break;
  852.         case CTL_PAGE_DOWN:
  853.            dxcrsr = 4;
  854.            dycrsr = 4;
  855.            break;
  856.         case CTL_HOME:
  857.            dxcrsr = -4;
  858.            dycrsr = -4;
  859.            break;
  860.         case CTL_END:
  861.            dxcrsr = -4;
  862.            dycrsr = 4;
  863.            break;
  864.         case PAGE_UP:
  865.            dxcrsr = 1;
  866.            dycrsr = -1;
  867.            break;
  868.         case PAGE_DOWN:
  869.            dxcrsr = 1;
  870.            dycrsr = 1;
  871.            break;
  872.         case HOME:
  873.            dxcrsr = -1;
  874.            dycrsr = -1;
  875.            break;
  876.         case END:
  877.            dxcrsr = -1;
  878.            dycrsr = 1;
  879.            break;
  880.         case UP_ARROW:
  881.            dycrsr = -1;
  882.            break;
  883.         case DOWN_ARROW:
  884.            dycrsr = 1;
  885.            break;
  886.         case LEFT_ARROW:
  887.            dxcrsr = -1;
  888.            break;
  889.         case RIGHT_ARROW:
  890.            dxcrsr = 1;
  891.            break;
  892.         case UP_ARROW_2:
  893.            dycrsr = -4;
  894.            break;
  895.         case DOWN_ARROW_2:
  896.            dycrsr = 4;
  897.            break;
  898.         case LEFT_ARROW_2:
  899.            dxcrsr = -4;
  900.            break;
  901.         case RIGHT_ARROW_2:
  902.            dxcrsr = 4;
  903.            break;
  904.         case 'z':
  905.         case 'Z':
  906.            zoom = (float)1.0;
  907.            break;
  908.         case '<':
  909.         case ',':
  910.            zoom /= (float)1.15;
  911.            break;
  912.         case '>':
  913.         case '.':
  914.            zoom *= (float)1.15;
  915.            break;
  916.         case SPACE:
  917.            xcjul = cr;
  918.            ycjul = ci;
  919.            goto finish;
  920.            /* break; */
  921.         case 'c':   /* circle toggle */
  922.         case 'C':   /* circle toggle */
  923.            mode = mode ^ 1;
  924.            break;
  925.         case 'l':
  926.         case 'L':
  927.            mode = mode ^ 2;
  928.            break;
  929.         case 'n':
  930.         case 'N':
  931.            show_numbers = 8 - show_numbers;
  932.            if(windows == 0 && show_numbers == 0)
  933.            {
  934.           Cursor_Hide();
  935.           cleartempmsg();
  936.           Cursor_Show();
  937.            }
  938.            break;
  939.         case 'p':
  940.         case 'P':
  941.            get_a_number(&cr,&ci);
  942.                exact = 1;
  943.                xcrsr = (int)(cvt.a*cr + cvt.b*ci + cvt.e + .5);
  944.                ycrsr = (int)(cvt.c*cr + cvt.d*ci + cvt.f + .5);
  945.                dxcrsr = dycrsr = 0;
  946.            break;
  947.         case 'h':   /* hide fractal toggle */
  948.         case 'H':   /* hide fractal toggle */
  949.            if(windows == 2)
  950.           windows = 3;
  951.            else if(windows == 3 && xd == sxdots)
  952.            {
  953.           RestoreRect(0, 0, xdots, ydots);
  954.           windows = 2;
  955.            }
  956.            break;
  957. #ifdef XFRACT
  958.         case ENTER:
  959.         break;
  960. #endif
  961.         case '0':
  962.         case '1':
  963.         case '2':
  964. /*        case '3': */  /* don't use '3', it's already meaningful */
  965.         case '4':
  966.         case '5':
  967.         case '6':
  968.         case '7':
  969.         case '8':
  970.         case '9':
  971.            if (which == JIIM)
  972.            {
  973.           SecretExperimentalMode = kbdchar - '0';
  974.           break;
  975.            }
  976.         default:
  977.            still = 0;
  978.         }  /* switch */
  979.         if(kbdchar == 's' || kbdchar == 'S')
  980.            goto finish;
  981.             if(dxcrsr > 0 || dycrsr > 0)
  982.                exact = 0;
  983.             xcrsr += dxcrsr;
  984.             ycrsr += dycrsr;
  985. #ifdef XFRACT
  986.         if (kbdchar == ENTER) {
  987.         /* We want to use the position of the cursor */
  988.         exact=0;
  989.         xcrsr = Cursor_GetX();
  990.         ycrsr = Cursor_GetY();
  991.         }
  992. #endif
  993.             
  994.         /* keep cursor in logical screen */
  995.        if(xcrsr >= xdots)
  996.           xcrsr = xdots -1, exact = 0;
  997.        if(ycrsr >= ydots)
  998.           ycrsr = ydots -1, exact = 0;
  999.        if(xcrsr < 0)
  1000.           xcrsr = 0, exact = 0;
  1001.        if(ycrsr < 0)
  1002.           ycrsr = 0, exact = 0;
  1003.         
  1004.             Cursor_SetPos(xcrsr,ycrsr);
  1005.      }  /* end while (keypressed) */
  1006.  
  1007.          if(exact == 0)
  1008.          {
  1009.         if(integerfractal)
  1010.         {
  1011.            cr = lx0[xcrsr]+lx1[ycrsr];  /* supports rotated zoom boxes! */
  1012.            ci = ly0[ycrsr]+ly1[xcrsr];
  1013.            cr /= (1L<<bitshift);
  1014.            ci /= (1L<<bitshift);
  1015.             }
  1016.         else
  1017.         {
  1018.            cr = dx0[xcrsr]+dx1[ycrsr];
  1019.            ci = dy0[ycrsr]+dy1[xcrsr];
  1020.         }
  1021.      }
  1022.      actively_computing = 1;
  1023.      if(show_numbers) /* write coordinates on screen */
  1024.      {
  1025.         char str[41];
  1026.         sprintf(str,"%16.14f %16.14f %3d",cr,ci,getcolor(xcrsr,ycrsr));
  1027.         if(windows == 0)
  1028.         {
  1029.            /* show temp msg will clear self if new msg is a 
  1030.               different length - pad to length 40*/
  1031.            while(strlen(str) < 40)
  1032.               strcat(str," ");
  1033.            str[40] = 0;   
  1034.            Cursor_Hide();
  1035.            actively_computing = 1;
  1036.            showtempmsg(str);
  1037.            Cursor_Show();
  1038.         }
  1039.         else
  1040.            displays(5, sydots-show_numbers, WHITE, BLACK, str,strlen(str));
  1041.      }
  1042.      iter = 1;
  1043.      old.x = old.y = lold.x = lold.y = 0;
  1044.      SaveC.x = init.x =  cr;
  1045.      SaveC.y = init.y =  ci;
  1046.          linit.x = (long)(init.x*fudge);
  1047.          linit.y = (long)(init.y*fudge);
  1048.      
  1049.      old_x = old_y = -1;
  1050. /*
  1051.  * MIIM code:
  1052.  * compute fixed points and use them as starting points of JIIM
  1053.  */
  1054.      if (which == JIIM && OKtoMIIM)
  1055.      {
  1056.         _CMPLX f1, f2, Sqrt;    /* Fixed points of Julia */
  1057.  
  1058.         Sqrt = ComplexSqrtFloat(1 - 4 * cr, -4 * ci);
  1059.         f1.x = (1 + Sqrt.x) / 2;
  1060.         f2.x = (1 - Sqrt.x) / 2;
  1061.         f1.y =  Sqrt.y / 2;
  1062.         f2.y = -Sqrt.y / 2;
  1063.  
  1064.         ClearQueue();
  1065.         maxhits = 1;
  1066.         EnQueueFloat((float)f1.x, (float)f1.y);
  1067.         EnQueueFloat((float)f2.x, (float)f2.y);
  1068.      }
  1069. /*
  1070.  * End MIIM code.
  1071.  */
  1072.      if(which == ORBIT)
  1073.            do_fractal_routines(cr, ci,PER_PIXEL);
  1074.      /* move window if bumped */
  1075.      if(windows==0 && xcrsr>xc && xcrsr < xc+xd && ycrsr>yc && ycrsr < yc+yd)
  1076.      {
  1077.         RestoreRect(xc,yc,xd,yd);
  1078.         if (xc == xd*2)
  1079.            xc = 2;
  1080.         else
  1081.            xc = xd*2;
  1082.         xoff = xc + xd /  2;
  1083.         SaveRect(xc,yc,xd,yd);
  1084.      }
  1085.      if(windows == 2)
  1086.      {
  1087.         fillrect(xdots, yc, xd-xdots, yd-show_numbers, color_dark);
  1088.         fillrect(xc   , ydots, xdots, yd-ydots-show_numbers, color_dark);
  1089.      }
  1090.      else
  1091.         fillrect(xc, yc, xd, yd, color_dark);
  1092.  
  1093.       } /* end if (keypressed) */
  1094.  
  1095.       if(which == JIIM)
  1096.       {
  1097.          if(hasinverse == 0)
  1098.             continue;
  1099. /*
  1100.  * MIIM code:
  1101.  * If we have MIIM queue allocated, then use MIIM method.
  1102.  */
  1103.      if (OKtoMIIM)
  1104.      {
  1105.         if (QueueEmpty())
  1106.         {
  1107.            if (maxhits < colors - 1 && maxhits < 5 &&
  1108.           (luckyx != 0.0 || luckyy != 0.0))
  1109.            {
  1110.           int i;
  1111.  
  1112.           lsize  = lmax   = 0;
  1113.           old.x  = new.x  = luckyx;
  1114.           old.y  = new.y  = luckyy;
  1115.           luckyx = luckyy = (float)0.0;
  1116.           for (i=0; i<199; i++)
  1117.           {
  1118.              old = ComplexSqrtFloat(old.x - cr, old.y - ci);
  1119.              new = ComplexSqrtFloat(new.x - cr, new.y - ci);
  1120.              EnQueueFloat( (float)new.x,  (float)new.y);
  1121.              EnQueueFloat((float)-old.x, (float)-old.y);
  1122.           }
  1123.           maxhits++;
  1124.            }
  1125.            else
  1126.           continue;        /* loop while (still) */
  1127.         }
  1128.  
  1129.         old = DeQueueFloat();
  1130.  
  1131. #if 0 /* try a different new method */
  1132.         if (lsize < (lmax / 8) && maxhits < 5)    /* NEW METHOD */
  1133.            if (maxhits < colors - 1)
  1134.            maxhits++;
  1135. #endif
  1136.         x = (int)(old.x * xfactor * zoom + xoff);
  1137.         y = (int)(old.y * yfactor * zoom + yoff);
  1138.         color = c_getcolor(x, y);
  1139.         if (color < maxhits)
  1140.         {
  1141.            c_putcolor(x, y, color + 1);
  1142.            new = ComplexSqrtFloat(old.x - cr, old.y - ci);
  1143.            EnQueueFloat( (float)new.x,  (float)new.y);
  1144.            EnQueueFloat((float)-new.x, (float)-new.y);
  1145.         }
  1146.      }
  1147.      else
  1148.      {
  1149. /*
  1150.  * end Msnyder code, commence if not MIIM code.
  1151.  */
  1152.      old.x -= cr;
  1153.      old.y -= ci;
  1154.      r = old.x*old.x + old.y*old.y;
  1155.      if(r > 10.0)
  1156.      {
  1157.          old.x = old.y = 0.0; /* avoids math error */
  1158.          iter = 1;
  1159.      }
  1160.      iter++;
  1161.      color = ((count++)>>5)%colors; /* chg color every 32 pts */
  1162.      if(color==0)
  1163.       color = 1;
  1164.  
  1165.      r = sqrt(old.x*old.x + old.y*old.y);
  1166.      new.x = sqrt(fabs((r + old.x)/2));
  1167.      if (old.y < 0)
  1168.         new.x = -new.x;
  1169.  
  1170.      new.y = sqrt(fabs((r - old.x)/2));
  1171.  
  1172.  
  1173.      switch (SecretExperimentalMode) {
  1174.         case 0:            /* unmodified random walk */
  1175.         default:
  1176.         if (rand() % 2)
  1177.         {
  1178.            new.x = -new.x;
  1179.            new.y = -new.y;
  1180.         }
  1181.         x = (int)(new.x * xfactor * zoom + xoff);
  1182.         y = (int)(new.y * yfactor * zoom + yoff);
  1183.         break;
  1184.         case 1:              /* always go one direction */
  1185.         if (SaveC.y < 0)
  1186.         {
  1187.            new.x = -new.x;
  1188.            new.y = -new.y;
  1189.         }
  1190.         x = (int)(new.x * xfactor * zoom + xoff);
  1191.         y = (int)(new.y * yfactor * zoom + yoff);
  1192.         break;
  1193.         case 2:            /* go one dir, draw the other */
  1194.         if (SaveC.y < 0)
  1195.         {
  1196.            new.x = -new.x;
  1197.            new.y = -new.y;
  1198.         }
  1199.         x = (int)(-new.x * xfactor * zoom + xoff);
  1200.         y = (int)(-new.y * yfactor * zoom + yoff);
  1201.         break;
  1202.         case 4:            /* go negative if max color */
  1203.         x = (int)(new.x * xfactor * zoom + xoff);
  1204.         y = (int)(new.y * yfactor * zoom + yoff);
  1205.         if (c_getcolor(x, y) == colors - 1)
  1206.         {
  1207.            new.x = -new.x;
  1208.            new.y = -new.y;
  1209.            x = (int)(new.x * xfactor * zoom + xoff);
  1210.            y = (int)(new.y * yfactor * zoom + yoff);
  1211.         }
  1212.         break;
  1213.         case 5:            /* go positive if max color */
  1214.         new.x = -new.x;
  1215.         new.y = -new.y;
  1216.         x = (int)(new.x * xfactor * zoom + xoff);
  1217.         y = (int)(new.y * yfactor * zoom + yoff);
  1218.         if (c_getcolor(x, y) == colors - 1)
  1219.         {
  1220.            x = (int)(new.x * xfactor * zoom + xoff);
  1221.            y = (int)(new.y * yfactor * zoom + yoff);
  1222.         }
  1223.         break;
  1224.         case 7:
  1225.         if (SaveC.y < 0)
  1226.         {
  1227.            new.x = -new.x;
  1228.            new.y = -new.y;
  1229.         }
  1230.         x = (int)(-new.x * xfactor * zoom + xoff);
  1231.         y = (int)(-new.y * yfactor * zoom + yoff);
  1232.         if(iter > 10)
  1233.         {
  1234.            if(mode == 0)            /* pixels  */
  1235.               c_putcolor(x, y, color);
  1236.            else if (mode & 1)            /* circles */
  1237.            {
  1238.               xbase = x;
  1239.               ybase = y;
  1240.               circle((int)(zoom*(xd >> 1)/iter),color);
  1241.            }
  1242.            if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0)
  1243.            {
  1244.               draw_line(x, y, old_x, old_y, color);
  1245.            }
  1246.            old_x = x;
  1247.            old_y = y;
  1248.         }
  1249.         x = (int)(new.x * xfactor * zoom + xoff);
  1250.         y = (int)(new.y * yfactor * zoom + yoff);
  1251.         break;
  1252.         case 8:            /* go in long zig zags */
  1253.         if (rancnt >= 300)
  1254.             rancnt = -300;
  1255.         if (rancnt < 0)
  1256.         {
  1257.             new.x = -new.x;
  1258.             new.y = -new.y;
  1259.         }
  1260.         x = (int)(new.x * xfactor * zoom + xoff);
  1261.         y = (int)(new.y * yfactor * zoom + yoff);
  1262.         break;
  1263.         case 9:            /* "random run" */
  1264.         switch (randir) {
  1265.             case 0:             /* go random direction for a while */
  1266.             if (rand() % 2)
  1267.             {
  1268.                 new.x = -new.x;
  1269.                 new.y = -new.y;
  1270.             }
  1271.             if (++rancnt > 1024)
  1272.             {
  1273.                 rancnt = 0;
  1274.                 if (rand() % 2)
  1275.                 randir =  1;
  1276.                 else
  1277.                 randir = -1;
  1278.             }
  1279.             break;
  1280.             case 1:             /* now go negative dir for a while */
  1281.             new.x = -new.x;
  1282.             new.y = -new.y;
  1283.             /* fall through */
  1284.             case -1:            /* now go positive dir for a while */
  1285.             if (++rancnt > 512)
  1286.                 randir = rancnt = 0;
  1287.             break;
  1288.         }
  1289.         x = (int)(new.x * xfactor * zoom + xoff);
  1290.         y = (int)(new.y * yfactor * zoom + yoff);
  1291.         break;
  1292.      } /* end switch SecretMode (sorry about the indentation) */
  1293.      } /* end if not MIIM */
  1294.       }
  1295.       else /* orbits */
  1296.       {
  1297.      if(iter < maxit)
  1298.      {
  1299.         color = (int)iter%colors;
  1300.         if(integerfractal)
  1301.         {
  1302.            old.x = lold.x; old.x /= fudge;
  1303.                old.y = lold.y; old.y /= fudge;
  1304.             }
  1305.             x = (int)((old.x - init.x) * xfactor * 3 * zoom + xoff);
  1306.             y = (int)((old.y - init.y) * yfactor * 3 * zoom + yoff);
  1307.         if((*ORBITCALC)())
  1308.            iter = maxit;
  1309.         else
  1310.            iter++;
  1311.      }
  1312.      else
  1313.      {
  1314.         x = y = -1;
  1315.         actively_computing = 0;
  1316.      }
  1317.       }
  1318.       if(which == ORBIT || iter > 10)
  1319.       {
  1320.      if(mode == 0)            /* pixels  */
  1321.         c_putcolor(x, y, color);
  1322.      else if (mode & 1)            /* circles */
  1323.      {
  1324.         xbase = x;
  1325.         ybase = y;
  1326.         circle((int)(zoom*(xd >> 1)/iter),color);
  1327.      }
  1328.      if ((mode & 2) && x > 0 && y > 0 && old_x > 0 && old_y > 0)
  1329.      {
  1330.         draw_line(x, y, old_x, old_y, color);
  1331.      }
  1332.      old_x = x;
  1333.      old_y = y;
  1334.       }
  1335.       old = new;
  1336.       lold = lnew;
  1337.    } /* end while(still) */
  1338. finish:
  1339.  
  1340. /*
  1341.  * Msnyder code:
  1342.  * free MIIM queue
  1343.  */
  1344.  
  1345.    Free_Queue();
  1346. /*
  1347.  * end Msnyder code.
  1348.  */
  1349.  
  1350.    if(kbdchar != 's'&& kbdchar != 'S')
  1351.    {
  1352.       Cursor_Hide();
  1353.       if(windows == 0)
  1354.      RestoreRect(xc,yc,xd,yd);
  1355.       else if(windows >= 2 )
  1356.       {
  1357.      if(windows == 2)
  1358.      {
  1359.         fillrect(xdots, yc, xd-xdots, yd, color_dark);
  1360.         fillrect(xc   , ydots, xdots, yd-ydots, color_dark);
  1361.      }
  1362.      else
  1363.         fillrect(xc, yc, xd, yd, color_dark);
  1364.          if(windows == 3 && xd == sxdots) /* unhide */
  1365.          {
  1366.             RestoreRect(0, 0, xdots, ydots);
  1367.             windows = 2;
  1368.          }
  1369.      Cursor_Hide();
  1370.      savehasinverse = hasinverse;
  1371.      hasinverse = 1;
  1372.      SaveRect(0,0,xdots,ydots);
  1373.      sxoffs = oldsxoffs;
  1374.      syoffs = oldsyoffs;
  1375.      RestoreRect(0,0,xdots,ydots);
  1376.      hasinverse = savehasinverse;
  1377.       }
  1378.    }
  1379.    Cursor_Destroy();
  1380. #ifdef XFRACT
  1381.    Cursor_EndMouseTracking();
  1382. #endif
  1383.    delete(line_buff);
  1384.    if (memory)            /* done with memory, free it */
  1385.    {
  1386.       farmemfree(memory);
  1387.       memory = NULL;
  1388.    }
  1389.  
  1390.    lookatmouse = oldlookatmouse;
  1391.    using_jiim = 0;
  1392.    calctype = oldcalctype;
  1393.    debugflag = old_debugflag; /* yo Chuck! */
  1394.    helpmode = oldhelpmode;
  1395.    if(kbdchar == 's' || kbdchar == 'S')
  1396.    {
  1397.       viewwindow = viewxdots = viewydots = 0;
  1398.       viewreduction = (float)4.2;
  1399.       viewcrop = 1;
  1400.       finalaspectratio = screenaspect;
  1401.       xdots = sxdots;
  1402.       ydots = sydots;
  1403.       dxsize = xdots - 1;
  1404.       dysize = ydots - 1;
  1405.       sxoffs = 0;
  1406.       syoffs = 0;
  1407.       freetempmsg();
  1408.    }
  1409.    else
  1410.       cleartempmsg();
  1411.    if (file != NULL)
  1412.       {
  1413.       fclose(file);
  1414.       file = NULL;
  1415.       dir_remove(tempdir,scrnfile);
  1416.       }
  1417.    show_numbers = 0;
  1418.    ungetakey(kbdchar);
  1419.  
  1420.    if (curfractalspecific->calctype == calcfroth)
  1421.       froth_cleanup();
  1422. }
  1423.